// ajax({
//     url: 'http://localhost:8888/test/third',
//     data: {
//         name: 'jack', age: 133
//     }
// })

/* 
    1.请求地址：url
    2.请求方式：method
    3.是否异步：async
    4.带给后端的数据：data
    5.请求头信息: headers
    6.是否解析响应体：dataType
    7.成功以后的函数：success
*/
function ajax(options = {}) {
    const { url, method, async, data, headers, dataType, success } = options
    if (!url) throw new Error('url为必填参数')

    if (!(method === undefined || /^(get|post)$/i.test(method)))
        throw new Error('method 目前只接受 "GET" 或者 "POST" 方式')

    if (!(async === undefined || typeof async === 'boolean'))
        throw new Error('async 只能接受  boolean 值')

    if (!(data === undefined || typeof data == "string" || Object.prototype.toString.call(data) === '[object Object]'))
        throw new Error('data 只能接受 字符串 或 对象 类型数据')

    //1-5 验证headers信息
    if (!(headers === undefined || Object.prototype.toString.call(headers) === '[object Object]')) {
        throw new Error('headers 需要传递一个"Object" 类型数据')
    }

    //1-6 验证dataType信息
    if (!(dataType === undefined || /^(string|json)$/i.test(dataType))) {
        throw new Error('dataType 目前只接受"string"和"json"两种值')
    }

    //1-7 验证success信息
    if (!(success === undefined || typeof success === 'function')) {
        throw new Error('success 需要传递一个"function"类型的值')
    }
    //2.准备默认值
    const _default = {
        url: url,
        method: method || 'GET',
        //空值运算(ES2020)?? 语法:值??值,只有左边为空的时候，才会使用右边
        // async: typeof async === 'boolean' ? async : true,
        async: async ?? true,
        data: data || '',
        // 因为headers 默认值是{'content-type':'application/x-www-form-urlencoded'}
        headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },
        dataType: dataType || 'JSON',
        success: success || function () { }
    }
    //2-1.调整一下 data 的值
    if (typeof _default.data === 'object') {
        _default.data = queryStringify(_default.data)
    }

    //2-2.调整url的值
    if (/^get$/i.test(_default.method) && _default.data) {
        _default.url += '?' + _default.data
    }
    const xhr = new XMLHttpRequest()
    xhr.open(_default.method, _default.url, _default.async)

    xhr.onload = () => {
        const res = _default.dataType === 'string' ? xhr.responseText : JSON.parse(xhr.responseText)
        _default.success(res)
    }

    // 设置请求头
    for (const key in _default.headers)
        xhr.setRequestHeader(key, _default.headers[key]);
    /^get$/i.test(_default.method) ? xhr.send() : xhr.send(_default.data)
}

function queryStringify(obj) {
    let str = ''
    for (let k in obj) {
        str += k + '=' + obj[k] + '&'
    }
    return str.slice(0, -1)
}

// 使用 Promise 语法 ，对ajax 进行二次封装
function pAjax(options = {}) {
    // 异步的 ajax 代码
    // 利用 Promise 语法
    const p = new Promise((resolve, rejact) => {
        // 书写 ajax 代码
        ajax({
            url: options.url,
            data: options.data,
            async: options.async,
            method: options.method,
            headers: options.headers,
            dataType: options.dataType,
            success(res) {
                resolve(res)
            }
        })
    })
    return p
}
